#pragma once
#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#include <cstddef>
/*关于扩容机制：一般的策略是设置扩容阈值，在阈值之下翻倍扩容，在阈值之后线性扩容*/
namespace bit
{
    class Buffer
    {
    public:
        //构造函数：
        Buffer(size_t size = default_size):_buffer(size), _writeidx(0), _readidx(0){}
        //1.向缓冲区里面写数据：
        void push(const char* data, size_t len)
        {
            //特殊情况——写入数据的长度大于 “可写入数据的长度” 时：1.扩容（测试环境——用于测试极限性能）； 2.阻塞； 3.直接返回false
            //1.扩容策略：
            while(len > writeAbleSize()) expandCapacity();
            //2.直接返回策略：
            // if(len > writeAbleSize())
            // {
            //     return false;   
            // }

            //1.1 先将数据拷贝到缓冲区中：
            std::copy(data, data + len, &_buffer[_writeidx]);

            //1.2 将写指针向后进行偏移：
            moveWriter(len);
            //return true;
        }
        //2.获取当前可写空间的剩余大小：
        size_t writeAbleSize()
        {
            return _buffer.size() - _writeidx;
        }
        //3.返回可读位置的起始地址：
        const char* begin()
        {
            return &_buffer[_readidx];
        }
        //4.返回可读的数据长度：
        size_t readAbleSize()
        {
            return _writeidx - _readidx;
        }
        //5.偏移读位置的指针：
        void moveReaded(size_t len)
        {
            if(len > readAbleSize())
            {
                std::cout << "警告：" << "当前读指针指向无效的数据" << std::endl;
            }
            _readidx += len;
        }
        //初始化缓冲区，重置读写位置：
        void reset()
        {
            _writeidx = 0;
            _readidx = 0;
        }
        //交换缓冲区：
        void swap(Buffer& tmp)
        {
            _buffer.swap(tmp._buffer);
            std::swap(_writeidx, tmp._writeidx);
            std::swap(_readidx, tmp._readidx);
        }
        //判断缓冲区是否为空：
        bool empty()
        {
            //关于缓冲区为空的理解：读写指针指向同一个位置的时候，代表已经没有有效数据能够以读取了
            return _writeidx == _readidx;
        }
        //返回当前缓冲区总的一个大小：
        size_t sizeofBuff()
        {
            return _buffer.size();
        }
    private:
        //偏移写位置的指针：
        void moveWriter(size_t len)
        {
            if(len + _writeidx > _buffer.size())
            {
                std::cout << "错误：" << "无效的写指针的偏移" << std::endl;
                abort();
            }
            _writeidx += len;
        }
        void expandCapacity()
        {
            //阈值之下翻倍扩容：
            if(_buffer.size() < threshold_size)
            {
                _buffer.resize(_buffer.size() + 2*increase_size);
            }
            //达到阈值线性扩容：
            else _buffer.resize(_buffer.size() + increase_size);
        }
    private:
        std::vector<char> _buffer;
        size_t _writeidx;   //记录写数据的位置
        size_t _readidx;    //记录读数据的位置

        const static size_t default_size;   
        const static size_t threshold_size;
        const static size_t increase_size;
    };
    const size_t Buffer::default_size = 10*1024*1024;   //10MB
    const size_t Buffer::threshold_size = 80*1024*1024; //80MB
    const size_t Buffer::increase_size = 15*1024*1024; //15MB 
}